package onlinebanking.server.modules;

import java.sql.Timestamp;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

import onlinebanking.constants.MSG;
import onlinebanking.exceptions.UserNotLoggedInException;
import onlinebanking.network.Message;
import onlinebanking.server.ServerEngine;
import onlinebanking.server.objects.Announcement;
import onlinebanking.server.objects.BankAccount;
import onlinebanking.server.objects.PersonalAccount;
import onlinebanking.server.objects.Session;
import onlinebanking.server.objects.Transaction;

public class InitTransactionModule extends Module {

	public InitTransactionModule(ServerEngine se, Message message) {
		this.serverengine = se;
		this.message = message;

	}

	public Message handleRequest() {
		Message response = new Message();
		if (!serverengine.isLoggedIn()) {
			response.setAsUserNotLoggedIn();
			return response;
		}

		try {

			BankAccount activeBA = serverengine.getSession()
					.getActiveBankAccount();
			if (activeBA == null) {
				Message m = new Message();
				m.setMsgType(MSG.INIT_FUNDSTRANSFER);
				m.setSuccess(false);
				m.addAttribute("reason", "No Active Accounts");
				return m;
			}

			String PAC = message.getString("PAC");
			String ConfirmPAC = message.getString("ConfirmPAC");
			
			if (!PAC.equals(ConfirmPAC)) {
				response.setSuccess(false);
				response.addAttribute("reason", "PACs dont match");
				return response;
			}

			int expDay = message.getInt("expDay");
			int expMonth = message.getInt("expMonth");
			int expYear = message.getInt("expYear");

			Transaction transaction = new Transaction();

			// set items for Transaction table;
			GregorianCalendar gCalendar = new GregorianCalendar();
			// gCalendar.set(year, Calendar.JANUARY, day, hour, mins, sec);
			gCalendar.set(expYear, expMonth, expDay, 0, 0, 0);
			Timestamp expiry = new Timestamp(gCalendar.getTimeInMillis());

			transaction.setExpiration(expiry);
			transaction.setProccessedOn(null);
			transaction.setTransactionTypeID(Transaction.FUNDS_TRANSFER);
			transaction.setTransactionStatusID(Transaction.PENDING);
			int intiatedby = serverengine.getSession().getUserAccount()
					.getpersonalaccountid();
			transaction.setInitiatedBy(intiatedby);
			int bankaccountid = activeBA.getBankAccountID();
			transaction.setBankAccountid(bankaccountid);

			// ================set items for the fundstransfer table=================

			int transactionid = transaction.insertToTransactionsTable();
			String destAccountno = message.getString("destAccountno");

			// getActiveBankAccount throws UserNotLoggedIn

			String srcAccountno = activeBA.getAccountno();
			double ammountTransfer = message.getDouble("ammountTransfer");

			int insertedPK = transaction.insertToFundsTransferTable(
					transactionid, ammountTransfer, srcAccountno,
					destAccountno, 0, 0, null, null);

			response.setMsgType(MSG.INIT_FUNDSTRANSFER);
			response.setSuccess(insertedPK > 0);
			
			if(insertedPK > 0){
				notifyOtherUsers(transactionid);
			}
			/*
			 * ADD CONFRIMATION OF TRANSACTION 
			 */
			
			ConfirmTransactionModule ctm = new ConfirmTransactionModule(this.serverengine, response);
			ctm.recordAuthentication(transactionid, Long.parseLong(PAC));

			return response;

		} catch (UserNotLoggedInException e) {
			Message m = new Message();
			m.setMsgType(MSG.USER_NOT_LOGGED_IN);
			return m;
		} catch (Exception e) {
			System.out.println("Unknown error");
			e.printStackTrace();
			Message m = new Message();
			m.setMsgType(MSG.INIT_FUNDSTRANSFER);
			m.setSuccess(false);
			m.addAttribute("reason", "Unknown error");
			return m;
		}
	}
	
	private void notifyOtherUsers(int transactionid){

		//detetmine other users;
		try {
			int accountowners[] = this.serverengine.getSession().getActiveBankAccount().getAccountOwners();
	
			int personalaccountid = this.serverengine.getSession().getUserAccount().getpersonalaccountid();
			String username = PersonalAccount.getUsernameByPersonalAccountid(personalaccountid);
			
			Date now = new Date();
			String notification = "A transaction was initated by "+ username+" on "+ now + " with transactionid "+ transactionid;
			
			for(int i = 0; i<accountowners.length; i++){
				Announcement.postPersonalAnnouncement(accountowners[i], personalaccountid, notification);
			}
			
		} catch (UserNotLoggedInException e) {
		}
		
	}
}
